﻿using AutoMapper.Internal.Mappers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Domain.Repositories;

namespace Himp.Platform
{
    /// <summary>
    /// 编码字典
    /// </summary>
    public class CodgDictService : CrudAppService<CodgDict, CodgDictDto, Guid, CodgDictInput, CodgDictCreateDto, CodgDictUpdateDto>
    {
        private IRepository<CodgDict, Guid> _codgDictRepository;
        private IRepository<CodgHistory,Guid> _codgHistoryRepository;
        private readonly IAbpDistributedLock _distributedLock;

        public CodgDictService(IRepository<CodgDict, Guid> codgDictRepository
            , IAbpDistributedLock distributedLock
            , IRepository<CodgHistory, Guid> codgHistoryRepository) : base(codgDictRepository)
        {
            _codgDictRepository = codgDictRepository;
            _distributedLock = distributedLock;
            _codgHistoryRepository = codgHistoryRepository;
        }

        /// <summary>
        /// 获取编码字典
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public override async Task<PagedResultDto<CodgDictDto>> GetListAsync(CodgDictInput input)
        {
            var iQuery = await _codgDictRepository.GetQueryableAsync();
            iQuery = iQuery.WhereIf(!string.IsNullOrEmpty(input.Filter), i => i.CodgDictName.Contains(input.Filter) || i.CatgeCodg.Contains(input.Filter));

            if (input.Pi == 0)
            {
                var itemsDto = ObjectMapper.Map<List<CodgDict>, List<CodgDictDto>>(iQuery.ToList());

                return new PagedResultDto<CodgDictDto>(itemsDto.Count, itemsDto);
            }
            else
            {
                var totalCount = iQuery.Count();
                var items = iQuery.Page(input.Pi, input.Ps);
                var itemsDto = ObjectMapper.Map<List<CodgDict>, List<CodgDictDto>>(items.ToList());

                return new PagedResultDto<CodgDictDto>(totalCount, itemsDto);
            }
        }

        /// <summary>
        /// 编码生成
        /// </summary>
        /// <param name="codg"></param>
        /// <returns></returns>
        public async Task<Dictionary<string,string>> PostGenerate(string catgeCodg)
        {
            var dict = new Dictionary<string, string>();
            var iQuery = await _codgDictRepository.WithDetailsAsync();
            var noDict = iQuery.FirstOrDefault(n => n.CatgeCodg == catgeCodg);

            if (noDict == null)
            {
                string codg = Guid.NewGuid().ToString("N");

                return dict;
            }

            string keyType = "codg/" + catgeCodg;

            await using (var handle = await _distributedLock.TryAcquireAsync(keyType))
            {
                if (handle != null)
                {
                    StringBuilder stringBuilder = new StringBuilder();

                    foreach (var item in noDict.CodgDictRules)
                    {
                        var index = 0;

                        if (item.CodgDictRuleType == EnumCodgDictRuleType.自然编号)
                        {
                            int.TryParse(item.DefaultValue, out index);
                            index++;

                            item.DefaultValue = index.ToString();
                        }

                        switch (item.CodgDictRuleType)
                        {
                            case EnumCodgDictRuleType.自然编号:  stringBuilder.Append(string.Format(item.Format, index));break;
                            case EnumCodgDictRuleType.年4: stringBuilder.Append(DateTime.Now.ToString("yyyy")); break;
                            case EnumCodgDictRuleType.年2: stringBuilder.Append(DateTime.Now.ToString("yy")); break;
                            case EnumCodgDictRuleType.月2: stringBuilder.Append(DateTime.Now.ToString("MM")); break;
                            case EnumCodgDictRuleType.日2: stringBuilder.Append(DateTime.Now.ToString("dd")); break;
                        }
                    }

                    string codg = stringBuilder.ToString();
                    dict.Add("codg", codg);
                    CodgHistory codgHistory = new CodgHistory(codg, noDict.Id);
                    await _codgHistoryRepository.InsertAsync(codgHistory);
                }
            }

            return dict;
        }
    }
}
